From 89849b914c5d9b5f2812901ce0315e1ac5d273d3 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Mon, 10 Jul 2006 13:12:41 -0600 Subject: [PATCH] [IA64] emulate PAL_HALT_LIGHT on domU This patch emulates Guest PAL_HALT_LIGHT on domU by using do_block and timer. It also adds the function of the timer interrupt to domU at the vcpu woke up. Signed-off-by: Atsushi SAKAI [warning fixes and static inlining] Signed-off-by: Alex Williamson --- xen/arch/ia64/vmx/vlsapic.c | 2 -- xen/arch/ia64/xen/domain.c | 11 +++++++++++ xen/arch/ia64/xen/hypercall.c | 4 +++- xen/arch/ia64/xen/xentime.c | 14 -------------- xen/include/asm-ia64/domain.h | 1 + xen/include/asm-ia64/time.h | 24 ++++++++++++++++++++++++ xen/include/asm-ia64/vcpu.h | 8 ++++++++ 7 files changed, 47 insertions(+), 17 deletions(-) diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index 4bb022d8cb..749607d8eb 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -165,8 +165,6 @@ void vtm_set_itc(VCPU *vcpu, uint64_t new_itc) #define TIMER_SLOP (50*1000) /* ns */ /* copy from timer.c */ -extern u64 cycle_to_ns(u64 cyle); - void vtm_set_itm(VCPU *vcpu, uint64_t val) { diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 9fe5dec74d..70868ef5f7 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -248,6 +248,14 @@ void startup_cpu_idle_loop(void) continue_cpu_idle_loop(); } +void hlt_timer_fn(void *data) +{ + struct vcpu *v = data; + if (vcpu_timer_expired(v)) + vcpu_pend_timer(v); + vcpu_unblock(v); +} + struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) { struct vcpu *v; @@ -303,6 +311,8 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) v->arch.breakimm = d->arch.breakimm; v->arch.last_processor = INVALID_PROCESSOR; } + if (!VMX_DOMAIN(v)) + init_timer(&v->arch.hlt_timer, hlt_timer_fn, v, v->processor); return v; } @@ -315,6 +325,7 @@ void free_vcpu_struct(struct vcpu *v) if (v->arch.privregs != NULL) free_xenheap_pages(v->arch.privregs, get_order_from_shift(XMAPPEDREGS_SHIFT)); + kill_timer(&v->arch.hlt_timer); } free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index 20ab2ecda3..f7d62f3b10 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -220,7 +220,9 @@ fw_hypercall (struct pt_regs *regs) } else { pal_halt_light_count++; - do_sched_op_compat(SCHEDOP_yield, 0); + set_timer(&v->arch.hlt_timer, + vcpu_get_next_timer_ns(v)); + do_sched_op_compat(SCHEDOP_block, 0); } regs->r8 = 0; regs->r9 = 0; diff --git a/xen/arch/ia64/xen/xentime.c b/xen/arch/ia64/xen/xentime.c index b1d32c50ae..c2e063d74c 100644 --- a/xen/arch/ia64/xen/xentime.c +++ b/xen/arch/ia64/xen/xentime.c @@ -42,20 +42,6 @@ static s_time_t stime_irq = 0x0; /* System time at last 'time updat unsigned long itc_scale, ns_scale; unsigned long itc_at_irq; -/* We don't expect an absolute cycle value here, since then no way - * to prevent overflow for large norminator. Normally this conversion - * is used for relative offset. - */ -u64 cycle_to_ns(u64 cycle) -{ - return (cycle * itc_scale) >> 32; -} - -u64 ns_to_cycle(u64 ns) -{ - return (ns * ns_scale) >> 32; -} - static inline u64 get_time_delta(void) { s64 delta_itc; diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index afaa40150b..eee899da19 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -170,6 +170,7 @@ struct arch_vcpu { unsigned long old_rsc; int mode_flags; fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */ + struct timer hlt_timer; struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ #define INVALID_PROCESSOR INT_MAX diff --git a/xen/include/asm-ia64/time.h b/xen/include/asm-ia64/time.h index c55fb1fbc4..be49a541a5 100644 --- a/xen/include/asm-ia64/time.h +++ b/xen/include/asm-ia64/time.h @@ -1,2 +1,26 @@ +#ifndef _XEN_IA64_TIME_H +#define _XEN_IA64_TIME_H + #include #include + +extern unsigned long itc_scale; +extern unsigned long ns_scale; + +/* We don't expect an absolute cycle value here, since then no way + * to prevent overflow for large norminator. Normally this conversion + * is used for relative offset. + */ +static inline u64 +cycle_to_ns(u64 cycle) +{ + return (cycle * itc_scale) >> 32; +} + +static inline u64 +ns_to_cycle(u64 ns) +{ + return (ns * ns_scale) >> 32; +} + +#endif /* _XEN_IA64_TIME_H */ diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index 326d651ead..35d06a81bb 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -4,9 +4,11 @@ // TODO: Many (or perhaps most) of these should eventually be // static inline functions +#include #include #include #include +#include #include typedef unsigned long UINT64; typedef unsigned int UINT; @@ -177,6 +179,12 @@ itir_mask(UINT64 itir) return (~((1UL << itir_ps(itir)) - 1)); } +static inline u64 +vcpu_get_next_timer_ns(VCPU *vcpu) +{ + return cycle_to_ns(PSCBX(vcpu, domain_itm) - ia64_get_itc()) + NOW(); +} + #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0) //#define vcpu_quick_region_check(_tr_regions,_ifa) 1 -- 2.30.2